package edu.ucsd.ccdb.tagPopup.othologyService;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import edu.ucsd.ccdb.MainConfiguration;
import edu.ucsd.ccdb.tagPopup.dataType.NIFOntologyTerm;

public class NifServiceWrapper {
	
	public static List<String> getAutoRequestList (String query) throws IOException, SAXException, ParserConfigurationException {
		
		List<String> result = new ArrayList<String> ();
		
		if (query.length() < 2 ) {
			return result;
		}
		
		String nifURL = NifServerConfiguration.SERVICE_NAME_GET_LIST_AUTOCOMPLETE + query + "?result_limit=" + NifServerConfiguration.LIMIT_QUERY_AUTOCOMPLETE ;
		URL url = new URL(nifURL);

		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(url.openStream());
		
		doc.getDocumentElement().normalize();
		
		if (MainConfiguration.DEBUG)
			System.out.println  ("Root elememt: " + doc.getDocumentElement().getNodeName() );
		
		NodeList nodeList = doc.getElementsByTagName("term");	 
		for (int i = 0; i < nodeList.getLength(); i ++){

			Element element = (Element) nodeList.item(i);
			NodeList fstTerm = element.getChildNodes();
			
			result.add( ( (Node) fstTerm.item(0)).getNodeValue().toLowerCase() );
		}
		
		return result;
	}
	
	public static NIFOntologyTerm getConcept (String term ) throws ParserConfigurationException, SAXException, IOException {
		NIFOntologyTerm result = null;
		
//		String nifURL = NifServerConfiguration.SERVICE_NAME_GET_CONCEPT + term + "?result_limit=" + NifServerConfiguration.LIMIT_QUERY_GET_CONCEPT;
		String nifURL = NifServerConfiguration.SERVICE_NAME_GET_CONCEPT + term ;
		URL urlStream = new URL(nifURL);
		
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(urlStream.openStream());
		
		doc.getDocumentElement().normalize();
		
		NodeList nodeList = doc.getElementsByTagName("class");		
		if (nodeList.getLength() > 0) {
			Element element = (Element) nodeList.item( 0);
			
			NodeList nameNodeList = element.getElementsByTagName("name");
			Element processElement = (Element) nameNodeList.item(0);
			NodeList processNodeList = processElement.getChildNodes();
			String name = ((Node) processNodeList.item(0)).getNodeValue() ;
			
			NodeList labelNodeList = element.getElementsByTagName("label");
			processElement = (Element) labelNodeList.item(0);
			processNodeList = processElement.getChildNodes();
			String label = ((Node) processNodeList.item(0)).getNodeValue() ;
			
			NodeList urlNodeList = element.getElementsByTagName("url");
			processElement = (Element) urlNodeList.item(0);
			processNodeList = processElement.getChildNodes();			
			String url = "";
			if (processNodeList.getLength() > 0 )
				url = ((Node) processNodeList.item(0)).getNodeValue() ;
			
			result = new NIFOntologyTerm(name, label, url);
		}
		
		return result;
	}
	
	public static String getNeurolexURL ( String term ) throws ParserConfigurationException, SAXException, IOException {
		
		String result = "";
		
		String query = "select $s $x $y {$s $prop \"" + term + "\"^^<http://www.w3.org/2001/XMLSchema#string>} ";
		
		String neurolexURL = NifServerConfiguration.NEUROLEX_SERVICE_URL + URLEncoder.encode(query, "UTF-8");
		URL urlStream = new URL (neurolexURL);
		
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(urlStream.openStream());
		doc.getDocumentElement().normalize();
		
		NodeList nodeList = doc.getElementsByTagName("results");
		
		if (nodeList.getLength() > 0 ) {
			Element element = (Element) nodeList.item(0);
			
			NodeList bindingNodeList = element.getElementsByTagName("binding");
			if (bindingNodeList.getLength() > 0 ) {
				element = (Element) bindingNodeList.item(0);
				NodeList processNodeList = element.getElementsByTagName("uri");
				element = (Element) processNodeList.item(0);
				processNodeList = element.getChildNodes();
				
				result = ((Node) processNodeList.item(0)).getNodeValue() ;
			}
		}
		
		return result;
	}
	
	/*
	 * fix broken image, 
	 */
	public static void fixAndGetImage ( String path ) throws IOException, ClassNotFoundException {
		
		URL url = new URL( NifServerConfiguration.SERVICE_FIX_IMAGE );
		                 
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		                   
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod( "POST" );
		ObjectOutputStream outputToServlet = new ObjectOutputStream(conn.getOutputStream());
					     
//		String path = "/CCDBProdZone/home/CCDB_DATA_USER/acquisition/project_10167/microscopy_12879/images/3_recon_512x512.jpg";
		                                
		outputToServlet.writeObject(path); 
		                                
		outputToServlet.flush();
		outputToServlet.close();
					
		ObjectInputStream inputFromServlet = new ObjectInputStream(conn.getInputStream());	
		Object o1 = inputFromServlet.readObject(); //It should return an Integer object. If there is an error, it will return a Null pointer
		                               
		System.out.println(o1); 		        		        
	}
	
	// testing
	public static void main (String [] args ) throws IOException, SAXException, ParserConfigurationException{
//		getAutoRequestList("bra");
		System.out.println (getNeurolexURL ("birnlex_1234") );
	}
	
}
